﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace POB
{
	class UnitInfo : IMenuItem
	{
		private XElement Xunit;
		private Texture2D icon;
		public string Name { get; set; }
		public int CostEnergie { get; set; }
		public List<AddOn> AddOns { get; set; }
		public string Describtion { get; set; }
		public int BuiltTime { get; set; }

		private World world;
		private Player player;
		private List<Slot> Slots;

		Texture2D itemBackground;
		Texture2D highlightedItemBackground;
		Texture2D menuDescribtionBackground;
		Texture2D menuNothingBackground;
		Texture2D unitProgress;
		Texture2D unitProgressBackground;
		Texture2D UnitProgressBorder;
		Texture2D done;
		Texture2D buttonX;
		Texture2D buttonA;
		
		public UnitInfo(XElement Xunit, World world, Player player)
		{
			this.Xunit = Xunit;
			this.world = world;
			this.player = player;
			this.icon = world.Content.Load<Texture2D>(Xunit.Attribute("Icon").Value);

			this.Name = Xunit.Name.LocalName;
			this.Describtion = Xunit.Attribute("Description").Value.Replace("\\n","\n");
			this.CostEnergie = Convert.ToInt32(Xunit.Attribute("CostEnergie").Value);
			this.BuiltTime = Convert.ToInt32(Xunit.Attribute("BuildTime").Value);
			this.AddOns = Xunit.Elements("AddOn")
				.Select<XElement, AddOn>(
				XElementAddOn => new AddOn(this, player)
				{
					CostEnergie = Convert.ToInt32(XElementAddOn.Attribute("CostEnergie").Value),
					Name = XElementAddOn.Attribute("Name").Value.Replace("\\n", "\n"),
					Describtion = XElementAddOn.Attribute("Description").Value.Replace("\\n", "\n"),
				})
				.ToList<AddOn>();

			this.Slots = new List<Slot>();

			this.itemBackground 			= player.World.Content.Load<Texture2D>(@"UI\UnitInfo");
			this.highlightedItemBackground	= player.World.Content.Load<Texture2D>(@"UI\highlightedUnitInfo");
			this.menuDescribtionBackground	= player.World.Content.Load<Texture2D>(@"UI\describtionBackground");
			this.menuNothingBackground		= player.World.Content.Load<Texture2D>(@"UI\UnitInfoNothingSelected");
			this.unitProgress				= player.World.Content.Load<Texture2D>(@"UI\UnitProgress");
			this.unitProgressBackground = player.World.Content.Load<Texture2D>(@"UI\UnitProgressBackground");
			this.UnitProgressBorder = player.World.Content.Load<Texture2D>(@"UI\UnitProgressBorder");
			this.done = player.World.Content.Load<Texture2D>(@"UI\Done");
			this.buttonX = player.World.Content.Load<Texture2D>(@"UI\xboxControllerButtonX");
			this.buttonA = player.World.Content.Load<Texture2D>(@"UI\xboxControllerButtonA");
		}

		public void CreateInstance(AddOn addOn)
		{
			Slot slot = Slots.Where<Slot>(s => s.State == SlotState.UnitReadyToLaunch).FirstOrDefault<Slot>();
			if(slot != null)
			{
				slot.FreeSlot();
				Slots.Remove(slot);
				world.Units.Add(new Unit(Xunit, world, player, addOn));
			}
		}

		public void DrawMenuIcon(SpriteBatch batch, Matrix horizontalMatrix, Matrix rotatedMatrix, bool selected)
		{
			if(selected)
				batch.Begin(horizontalMatrix * Matrix.CreateTranslation(-10f, -10f, 0f));
			else
				batch.Begin(horizontalMatrix);

			int unitsDone = Slots.Where<Slot>(s => s.State == SlotState.UnitReadyToLaunch).Count<Slot>();
			bool canDoAction = (player.Energie >= CostEnergie && unitsDone > 0) || player.Slots.Where<Slot>(s => s.State == SlotState.Empty).Count<Slot>() > 0;

			batch.Draw(selected ? highlightedItemBackground : itemBackground,
				new Vector2(-85, -85),
				canDoAction ? Color.White : Color.Gray);

			batch.DrawString(player.World.UI36, Name, new Vector2(10f,-40f), Color.Black, 0f, player.World.UI36.MeasureString(Name) / 2, 1f, SpriteEffects.None, 0f);

			batch.DrawString(player.World.UI21, CostEnergie.ToString() , new Vector2(-40, -16), Color.Black);
			batch.DrawString(player.World.UI21, BuiltTime.ToString() + "s", new Vector2(-60, 13), Color.Black);

			for(int i = 0; i < this.Slots.Count; i++)
			{
				Vector2 pos;
				if(i == 0)
					pos = new Vector2(-67f, 50f);
				else if(i > 3)
					pos = new Vector2(-67f + 55f * (i - 3), 50f);
				else
					pos = new Vector2(-67f + 55f * (i - 1), 72f);

				batch.Draw(UnitProgressBorder, pos, Color.White);

				batch.Draw(unitProgress, pos, new Rectangle(0,0,(int)((unitProgress.Width - 5) * this.Slots[i].BuildProgess), unitProgress.Height), Color.White);

				if(this.Slots[i].State == SlotState.UnitReadyToLaunch)
					batch.Draw(unitProgressBackground, pos, Color.White);

				if(this.Slots[i].State == SlotState.UnitReadyToLaunch)
				{
					batch.Draw(done, pos, Color.White);
				}
			}

			batch.End();

		} 

		public void DrawIfSelected(SpriteBatch batch, Matrix matrix)
		{
			batch.Begin(Matrix.CreateTranslation(-175f, -155f, 0f) * matrix);

			float middle = menuDescribtionBackground.Width / 2;
			int unitsDone = Slots.Where<Slot>(s => s.State == SlotState.UnitReadyToLaunch).Count<Slot>();
			bool canDoAction = (player.Energie >= CostEnergie && unitsDone > 0) || player.Slots.Where<Slot>(s => s.State == SlotState.Empty).Count<Slot>() > 0;

			batch.Draw(menuDescribtionBackground, Vector2.Zero, canDoAction? Color.White : Color.Gray);

			batch.DrawString(player.World.UI36, Name, new Vector2(middle, 30), Color.Black, 0f, player.World.UI36.MeasureString(Name) / 2, 1f, SpriteEffects.None, 0f);
			batch.DrawString(player.World.UI21, Describtion, new Vector2(middle, 60), Color.Black, 0f, new Vector2(player.World.UI21.MeasureString(Describtion).X / 2, 0f), 1f, SpriteEffects.None, 0f);

			batch.DrawString(player.World.UI21, CostEnergie.ToString(), new Vector2(315, 230), Color.Black);
			batch.DrawString(player.World.UI21, BuiltTime.ToString() + "sec", new Vector2(15, 225), Color.Black);

			if(Slots.Where<Slot>(s => s.State == SlotState.UnitReadyToLaunch).Count<Slot>() == 0)
			{
				batch.DrawString(player.World.UI21, "No Unit", new Vector2(player.World.UI21.MeasureString("No Unit").X / -2 + middle, 260), Color.Black);
			}
			else if(player.Energie < CostEnergie)
			{
				batch.DrawString(player.World.UI21, "No Energie", new Vector2(player.World.UI21.MeasureString("No Energie").X / -2 + middle, 260), Color.Black);
			}
			else
			{ 
				batch.Draw(buttonA, new Rectangle(95, 265, 35, 35), Color.White);
				batch.DrawString(player.World.UI21, "Launch", new Vector2(140, 260), Color.Black);
			}

			if(player.Slots.Where<Slot>(s => s.State == SlotState.Empty).Count<Slot>() > 0)
			{
				batch.Draw(buttonX, new Rectangle(95, 300, 35, 35), Color.White);
				batch.DrawString(player.World.UI21, "Build", new Vector2(140, 295), Color.Black);
			}
			else
			{
				batch.DrawString(player.World.UI21, "No Slot", new Vector2(player.World.UI21.MeasureString("No Slot").X / -2 + middle, 295), Color.Black);
			}

			batch.End();
		}

		public void Selected(CircleMenu parentMenu, InputState input, PlayerIndex playerIndex)
		{
			if(input.IsNewButtonPress(Buttons.A, playerIndex))
			{
				Slot slot = Slots.Where<Slot>(s => s.State == SlotState.UnitReadyToLaunch).FirstOrDefault<Slot>();
				if(slot != null && player.Energie >= CostEnergie)
					parentMenu.NavigateToSubMenu(AddOns.ToList<IMenuItem>());
			}

			if(input.IsNewButtonPress(Buttons.X, playerIndex))
			{
				Slot slot = player.Slots.Where<Slot>(s => s.State == SlotState.Empty).FirstOrDefault<Slot>();
				if(slot != null)
				{
					slot.StartBuildingUnit(this);
					Slots.Add(slot);
				} 
			}

			if(input.IsNewButtonPress(Buttons.Y, playerIndex))
			{
				Slot slot = this.Slots.LastOrDefault<Slot>();
				if(slot != null)
				{
					slot.FreeSlot();
					Slots.Remove(slot);
				}
			}
		}


		public void DrawNothingSelected(SpriteBatch spriteBatch, Matrix matrix)
		{
			spriteBatch.Begin(matrix);

			spriteBatch.Draw(menuNothingBackground, new Vector2(menuNothingBackground.Width - 20, menuNothingBackground.Height) / -2, Color.White);

			spriteBatch.End();
		}

		public void NothingSelected(CircleMenu parentMenu, InputState input, PlayerIndex playerIndex)
		{
		}
	}
}
